﻿#region COPYRIGHT
//--------------------------------------------------------------------------------
// <copyright file="CollisionDebugDraw.cs" company="starLiGHT Entertainment Studios">
//    Copyright (c) 2010, 2011
//       Roland Rosenkranz (Glatzemann@email.de)
// </copyright>
// <license>
//   This file is part of starLiGHT.Collision.
//
//   starLiGHT.Collision is free software: you can redistribute it and/or modify
//   it under the terms of the GNU Lesser General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   starLiGHT.Collision is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU Lesser General Public License for more details.
//
//   You should have received a copy of the GNU Lesser General Public License
//   along with starLiGHT.Collision. If not, see http://www.gnu.org/licenses/.
//    
//   ADDITIONAL (commercial) LICENSES for starLiGHT.Collision are available on request.
// </license>
// <version>
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev:: 3345                  $:  Revision of last commit *
// * $Author:: unknown            $:  Author of last commit   *
// * $Date:: 2011-01-13 16:01:08 #$:  Date of last commit     *
// ************************************************************
// </version>
//--------------------------------------------------------------------------------
#endregion

namespace starLiGHT.Collision
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using starLiGHT.Collections;
    #endregion

    public class DefaultCollisionDebugDraw : ICollisionDebugDraw
    {
        private bool drawBoxes;
        private bool drawCircles;
        private bool drawHulls;
        private FastList<RectangleF> userRectangles = new FastList<RectangleF>();
        private FastList<UserLine> userLines = new FastList<UserLine>();

        public DefaultCollisionDebugDraw()
        {
            this.drawBoxes = true;
        }

        public DefaultCollisionDebugDraw(bool drawBoundingBoxes, bool drawBoundingCircles, bool drawBoundingHulls)
        {
            this.drawBoxes = drawBoundingBoxes;
            this.drawCircles = drawBoundingCircles;
            this.drawHulls = drawBoundingHulls;
        }

        public bool DrawBoundingBoxes
        {
            get { return this.drawBoxes; }
            set { this.drawBoxes = value; }
        }

        public bool DrawBoundingCircles
        {
            get { return this.drawCircles; }
            set { this.drawCircles = value; }
        }

        public bool DrawBoundingHulls
        {
            get { return this.drawHulls; }
            set { this.drawHulls = value; }
        }

        public void DrawBoundingBox(SpriteBatch spriteBatch, ICollidable2D c)
        {
            if (!this.drawBoxes || c == null)
            {
                return;
            }

            spriteBatch.DrawBox(c.WorldBoundingRectangle, Color.Red);
        }

        public void DrawBoundingCircle(SpriteBatch spriteBatch, ICollidable2D c)
        {
            if (!this.drawCircles || c == null)
            {
                return;
            }

            CircleF circle = c.BoundingCircle;
            Transform2D transform = c.Transform;
            circle.Center = Vector2.Transform(circle.Center, transform.TransformationMatrix);
            circle.Radius *= transform.Scale.HasValue ? (transform.Scale.Value.X + transform.Scale.Value.Y) * 0.5f : 1.0f;

            spriteBatch.DrawCircle(circle.Center, circle.Radius, 32, Color.Green);
        }

        public void DrawBoundingHull(SpriteBatch spriteBatch, ICollidable2D c)
        {
            if (!this.drawHulls || c == null)
            {
                return;
            }

            if (c.Hull != null)
            {
                Vector2 p1, p2;

                for (int i = 0; i < c.Hull.VertexCount; i++)
                {
                    p1 = Vector2.Transform(c.Hull[i], c.Transform.TransformationMatrix);
                    p2 = Vector2.Transform(c.Hull[i + 1 < c.Hull.VertexCount ? i + 1 : 0], c.Transform.TransformationMatrix);
                    spriteBatch.DrawLine(p1, p2, Color.Yellow);
                }
            }
        }

        public void DrawUserRectangles(SpriteBatch spriteBatch)
        {
            foreach (RectangleF r in this.userRectangles)
            {
                spriteBatch.DrawBox(r, Color.Blue);
            }

            this.userRectangles.Clear();
        }

        public void DrawUserLines(SpriteBatch spriteBatch)
        {
            foreach (UserLine ul in this.userLines)
            {
                spriteBatch.DrawLine(ul.Start, ul.End, ul.Color);
            }

            this.userLines.Clear();
        }

        public void QueueUserRectangle(RectangleF rect)
        {
            this.userRectangles.Add(rect);
        }

        public void QueueUserLine(Vector2 start, Vector2 end, Color color)
        {
            this.userLines.Add(new UserLine(start, end, color));
        }
    }
}
